﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace ZiZi.Graphics.Sampling.VanDerCorput
{
    public class VanDerCorputSequence
    {
        /// cf : [warren01]  Hacker's Delight, Henry S. Warren, 2001, ISBN:0201914654
        /// cf : http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoint.pdf
        public static double Value(uint index)
        {
            index = (index << 16) | (index >> 16);
            index = ((index & 0x55555555u) << 1) | ((index & 0xAAAAAAAAu) >> 1);
            index = ((index & 0x33333333u) << 2) | ((index & 0xCCCCCCCCu) >> 2);
            index = ((index & 0x0F0F0F0Fu) << 4) | ((index & 0xF0F0F0F0u) >> 4);
            index = ((index & 0x00FF00FFu) << 8) | ((index & 0xFF00FF00u) >> 8);
            return (double) (index)*2.3283064365386963e-10; // / 0x100000000
        }

        /// <summary>
        /// Generate Van Der Couput Sequence.
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="result"></param>
        public static void GenerateSequence(int startIndex, int endIndex, ref List<double> result)
        {
            if (startIndex >= endIndex || startIndex < 0)
                return;

            result.Clear();
            int count = endIndex - startIndex + 1;
            result.Capacity = count;

            uint start = (uint) startIndex;
            uint i = 0;

            for (int it = 0; it < count; ++it, ++i)
            {
                result.Add(VanDerCorputSequence.Value(start + i));
            }
        }
    }
}
